﻿//*************************************************************************************
//* 作    者： 邹杭特
//* 创建时间： 2021-12-01 10:52:28
//* 描    述： 网络客户端

//* ************************************************************************************
using System;
using System.Net.Sockets;

using UnityEngine;

namespace UFrame.NetSocket
{
    public class SocketClient
    {
        private IClient m_client;
        private ClientBuilder m_clientBuilder;
        private int m_refreshTimer;
        public bool Connected { get; private set; }

        public void CreateClient<Serialiser>(string ip, int tcpPort, int udpPort) where Serialiser : class, IPacketSerialiser
        {
            m_clientBuilder = new ClientBuilder();
            m_clientBuilder.UseIp(ip);
            m_clientBuilder.UseTcp(tcpPort);
            m_clientBuilder.UseUdp(udpPort);
            m_clientBuilder.UseLog<SocketLogger>();
            m_clientBuilder.UsePacketSerialiser<Serialiser>();
        }

        public void CreateGooglePbClient(string ip, int tcpPort, int udpPort)
        {
            CreateClient<GooglePbNetSerialiser>(ip, tcpPort, udpPort);
        }

        public void CreateGooglePbTcpClient(string ip, int tcpPort)
        {
            CreateClient<GooglePbNetSerialiser>(ip, tcpPort, 0);
        }

        public void CreateGooglePbUdpClient(string ip, int udpPort)
        {
            CreateClient<GooglePbNetSerialiser>(ip, 0, udpPort);
        }

        public void CreateProtobufClient(string ip, int tcpPort, int udpPort)
        {
            CreateClient<ProtoBufNetSerialiser>(ip, tcpPort, udpPort);
        }

        internal void CloseClient()
        {
            if (m_client != null)
                m_client.Stop();
        }

        public void CreateProtobufTcpClient(string ip, int tcpPort)
        {
            CreateClient<ProtoBufNetSerialiser>(ip, tcpPort, 0);
        }

        public void CreateProtobufUdpClient(string ip, int udpPort)
        {
            CreateClient<ProtoBufNetSerialiser>(ip, 0, udpPort);
        }

        public void RegisterPacketHandler<TPacketHandler>(ushort opcode) where TPacketHandler : IPacketHandler
        {
            m_clientBuilder.RegisterPacketHandler<TPacketHandler>(opcode);
        }

        public ConnectResult StartConnect()
        {
            if (m_clientBuilder == null)
            {
                return new ConnectResult("m_clientBuilder == null ,you client may not created!");
            }

            if (m_client == null)
            {
                m_client = m_clientBuilder.Build();
                m_client.Connected = OnConnected;
                m_client.Disconnected = OnDisConnected;
            }
            return m_client.Connect();
        }

        protected virtual void OnDisConnected(object sender, Socket socket)
        {
            Debug.Log("client disconnected!");
            Connected = false;
        }

        protected virtual void OnConnected(object sender, Socket socket)
        {
            Debug.Log("client connected!");
            Connected = true;
            if (m_refreshTimer > 0)
                TimerAgent.Instance.StopTimer(m_refreshTimer);
            m_refreshTimer = TimerAgent.Instance.RegistLoop(RefreshClient, 0.02f, Timer.TimerUpdateType.LateUpdate);
        }

        protected bool RefreshClient()
        {
            if (m_client != null)
            {
                m_client.MainThreadRefresh();
            }
            return !Connected;
        }

        public void Send(ushort opcode, byte[] bytes)
        {
            if (m_client != null)
            {
                m_client.SendTcp(opcode, bytes);
            }
        }

        public void Send<T>(ushort opcode, T packet)
        {
            if (m_client != null)
            {
                m_client.SendTcp(opcode, packet);
            }
        }
    }
}